#include <stdio.h>
#include <stdint.h>
#include <time.h>

#define RNG_A 1664525
#define RNG_B 1013904223
unsigned int rng_state;

void my_srand(unsigned int i)
{
	rng_state = i;
}

unsigned int my_rand()
{
	rng_state = rng_state * RNG_A + RNG_B;
	return rng_state;
}

union uint32_t_float
{
	unsigned int i;
	float f;
};

float float_rand()
{
	union uint32_t_float tmp;

	tmp.i = (my_rand() & 0x007fffff) | 0x3f800000;
	
	return tmp.f - 1;
}

int main()
{
	//my_srand(time(NULL));

	for (int i = 0; i < 100; i++)
			printf("%f\n", float_rand());

	return 0;
}

#if 0
/*
 * intel
 */
0000000000001169 <my_srand>:
    1169:	f3 0f 1e fa          	endbr64 
    116d:	55                   	push   %rbp
    116e:	48 89 e5             	mov    %rsp,%rbp
    1171:	89 7d fc             	mov    %edi,-0x4(%rbp)		// (rbp-0x4)=parameter
    1174:	8b 45 fc             	mov    -0x4(%rbp),%eax		// eax=parameter
    1177:	89 05 97 2e 00 00    	mov    %eax,0x2e97(%rip)        # 4014 <rng_state>	// global variable=parameter
    117d:	90                   	nop
    117e:	5d                   	pop    %rbp
    117f:	c3                   	retq   

0000000000001180 <my_rand>:
    1180:	f3 0f 1e fa          	endbr64 
    1184:	55                   	push   %rbp
    1185:	48 89 e5             	mov    %rsp,%rbp
    1188:	8b 05 86 2e 00 00    	mov    0x2e86(%rip),%eax        # 4014 <rng_state>	eax=global variable
    118e:	69 c0 0d 66 19 00    	imul   $0x19660d,%eax,%eax		// eax=eax*0x19660d-->0x6286edd6*0x19660d=0x9C673FD8357DE, eax=0xfd8357de
    1194:	05 5f f3 6e 3c       	add    $0x3c6ef35f,%eax			// eax=eax+0x3c6ef35f -> 0xfd8357de+0x3c6ef35f=139F24B3D, eax=0x39f24b3d
    1199:	89 05 75 2e 00 00    	mov    %eax,0x2e75(%rip)        # 4014 <rng_state>	// global variable=eax=0x39f24b3d
    119f:	8b 05 6f 2e 00 00    	mov    0x2e6f(%rip),%eax        # 4014 <rng_state>	// return global variable value --> 0x39f24b3d
    11a5:	5d                   	pop    %rbp
    11a6:	c3                   	retq   

00000000000011a7 <float_rand>:
    11a7:	f3 0f 1e fa          	endbr64 
    11ab:	55                   	push   %rbp
    11ac:	48 89 e5             	mov    %rsp,%rbp
    11af:	48 83 ec 10          	sub    $0x10,%rsp
    11b3:	b8 00 00 00 00       	mov    $0x0,%eax
    11b8:	e8 c3 ff ff ff       	callq  1180 <my_rand>	// my_rand()
    11bd:	25 ff ff 7f 00       	and    $0x7fffff,%eax	// eax=global variable(0x39f24b3d) & 0x7fffff = 0x724b3d
    11c2:	0d 00 00 80 3f       	or     $0x3f800000,%eax	// eax=0x724b3d|0x3f800000 = 0x3ff24b3d
    11c7:	89 45 fc             	mov    %eax,-0x4(%rbp)	// (rbp-0x4)=eax=0x3ff24b3d
    11ca:	f3 0f 10 45 fc       	movss  -0x4(%rbp),%xmm0	// xmm0=(rbp-0x4)=0x3ff24b3d=1.8929210901260376
    11cf:	f3 0f 10 0d 31 0e 00 	movss  0xe31(%rip),%xmm1        # 2008 <_IO_stdin_used+0x8> (rip-0xe31)=0x3f800000=1 xmm1=0x3f800000
    11d6:	00 
    11d7:	f3 0f 5c c1          	subss  %xmm1,%xmm0		// 0x3ff24b3d-0x3f800000=0x3f64967a=0.8929210901260376
    11db:	c9                   	leaveq 
    11dc:	c3                   	retq   

00000000000011dd <main>:
    11dd:	f3 0f 1e fa          	endbr64 
    11e1:	55                   	push   %rbp
    11e2:	48 89 e5             	mov    %rsp,%rbp
    11e5:	48 83 ec 10          	sub    $0x10,%rsp
    11e9:	bf 00 00 00 00       	mov    $0x0,%edi
    11ee:	e8 7d fe ff ff       	callq  1070 <time@plt>
    11f3:	89 c7                	mov    %eax,%edi			// edi=0x6286edd6=1653009878
    11f5:	e8 6f ff ff ff       	callq  1169 <my_srand>
    11fa:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)
    1201:	eb 23                	jmp    1226 <main+0x49>
    1203:	b8 00 00 00 00       	mov    $0x0,%eax
    1208:	e8 9a ff ff ff       	callq  11a7 <float_rand>
    120d:	f3 0f 5a c0          	cvtss2sd %xmm0,%xmm0		// xmm0=0x3fec92cf40000000
    1211:	48 8d 3d ec 0d 00 00 	lea    0xdec(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    1218:	b8 01 00 00 00       	mov    $0x1,%eax
    121d:	e8 3e fe ff ff       	callq  1060 <printf@plt>	// 0.892921
    1222:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)
    1226:	83 7d fc 63          	cmpl   $0x63,-0x4(%rbp)
    122a:	7e d7                	jle    1203 <main+0x26>
    122c:	b8 00 00 00 00       	mov    $0x0,%eax
    1231:	c9                   	leaveq 
    1232:	c3                   	retq   
    1233:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
    123a:	00 00 00 
    123d:	0f 1f 00             	nopl   (%rax)

/*
 * arm
 */
00000000004005ac <my_srand>:
  4005ac:	d10043ff 	sub	sp, sp, #0x10
  4005b0:	b9000fe0 	str	w0, [sp, #12]
  4005b4:	b0000080 	adrp	x0, 411000 <time@GLIBC_2.17>
  4005b8:	9100f000 	add	x0, x0, #0x3c
  4005bc:	b9400fe1 	ldr	w1, [sp, #12]
  4005c0:	b9000001 	str	w1, [x0]
  4005c4:	d503201f 	nop
  4005c8:	910043ff 	add	sp, sp, #0x10
  4005cc:	d65f03c0 	ret

00000000004005d0 <my_rand>:
  4005d0:	b0000080 	adrp	x0, 411000 <time@GLIBC_2.17>
  4005d4:	9100f000 	add	x0, x0, #0x3c
  4005d8:	b9400001 	ldr	w1, [x0]
  4005dc:	528cc1a0 	mov	w0, #0x660d                	// #26125
  4005e0:	72a00320 	movk	w0, #0x19, lsl #16
  4005e4:	1b007c21 	mul	w1, w1, w0
  4005e8:	529e6be0 	mov	w0, #0xf35f                	// #62303
  4005ec:	72a78dc0 	movk	w0, #0x3c6e, lsl #16
  4005f0:	0b000021 	add	w1, w1, w0
  4005f4:	b0000080 	adrp	x0, 411000 <time@GLIBC_2.17>
  4005f8:	9100f000 	add	x0, x0, #0x3c
  4005fc:	b9000001 	str	w1, [x0]
  400600:	b0000080 	adrp	x0, 411000 <time@GLIBC_2.17>
  400604:	9100f000 	add	x0, x0, #0x3c
  400608:	b9400000 	ldr	w0, [x0]
  40060c:	d65f03c0 	ret

0000000000400610 <float_rand>:
  400610:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400614:	910003fd 	mov	x29, sp
  400618:	97ffffee 	bl	4005d0 <my_rand>
  40061c:	12005800 	and	w0, w0, #0x7fffff
  400620:	32091800 	orr	w0, w0, #0x3f800000
  400624:	b9001ba0 	str	w0, [x29, #24]
  400628:	bd401ba1 	ldr	s1, [x29, #24]
  40062c:	1e2e1000 	fmov	s0, #1.000000000000000000e+00
  400630:	1e203820 	fsub	s0, s1, s0
  400634:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400638:	d65f03c0 	ret

000000000040063c <main>:
  40063c:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400640:	910003fd 	mov	x29, sp
  400644:	d2800000 	mov	x0, #0x0                   	// #0
  400648:	97ffff86 	bl	400460 <time@plt>
  40064c:	97ffffd8 	bl	4005ac <my_srand>
  400650:	b9001fbf 	str	wzr, [x29, #28]
  400654:	14000009 	b	400678 <main+0x3c>
  400658:	97ffffee 	bl	400610 <float_rand>
  40065c:	1e22c000 	fcvt	d0, s0
  400660:	90000000 	adrp	x0, 400000 <_init-0x428>
  400664:	911d0000 	add	x0, x0, #0x740
  400668:	97ffff8e 	bl	4004a0 <printf@plt>
  40066c:	b9401fa0 	ldr	w0, [x29, #28]
  400670:	11000400 	add	w0, w0, #0x1
  400674:	b9001fa0 	str	w0, [x29, #28]
  400678:	b9401fa0 	ldr	w0, [x29, #28]
  40067c:	71018c1f 	cmp	w0, #0x63
  400680:	54fffecd 	b.le	400658 <main+0x1c>
  400684:	52800000 	mov	w0, #0x0                   	// #0
  400688:	a8c27bfd 	ldp	x29, x30, [sp], #32
  40068c:	d65f03c0 	ret


#endif

